﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LiteratureManage.Domain.IntegrationTest
{
    using Castle.Services.Transaction;
    using Castle.Windsor;
    using Castle.Facilities.NHibernateIntegration;
    using NUnit.Framework;
    using NHibernate;
    using ITx = Castle.Services.Transaction.ITransaction;

    public class TestBase
    {
        protected static readonly string SessionKey = "CallContext.session";
        protected IWindsorContainer Container;
        protected ISessionManager SessionManager;
        protected ITransactionManager TransactionManager;

        [SetUp]
        public virtual void SetUp()
        {
            this.Container = ContainerBuilder.Build();
            this.SessionManager = this.Container.Resolve<ISessionManager>();
            this.TransactionManager = this.Container.Resolve<ITransactionManager>();
            System.Runtime.Remoting.Messaging.CallContext.SetData(SessionKey, this.SessionManager.OpenSession());
        }

        [TearDown]
        public virtual void TearDown()
        {
            var session = (ISession)System.Runtime.Remoting.Messaging.CallContext.GetData(SessionKey);

            if (session != null)
            {
                session.Flush();
                session.Dispose();
            }

            this.Container.Dispose();
        }


        public void DoTrans(Action action)
        {
            var tx = this.TransactionManager.CreateTransaction(TransactionMode.RequiresNew, IsolationMode.Serializable);
            try
            {
                tx.Begin();
                action();
                tx.Commit();
            }
            catch (Exception)
            {
                tx.Rollback();
            }
            finally
            {
                this.TransactionManager.Dispose(tx);
            }
        }

        public T DoTrans<T>(Func<T> func)
        {
            T result = default(T);
            var tx = this.TransactionManager.CreateTransaction(TransactionMode.RequiresNew, IsolationMode.Serializable);
            try
            {
                tx.Begin();
                result = func();
                tx.Commit();
            }
            catch (Exception)
            {
                tx.Rollback();
            }
            finally
            {
                this.TransactionManager.Dispose(tx);
            }
            return result;
        }
    }
}
